#pragma once

#include <windows.h>
#include <stdio.h>
#include <intrin.h>

#pragma intrinsic(_InterlockedExchangeAdd)
#pragma intrinsic(_InterlockedExchange)
#pragma intrinsic(_InterlockedIncrement)
#pragma intrinsic(_InterlockedDecrement)

#define LOG_RINGBUFFERSIZE		64//(1024*1024)
#define LOG_RINGBUFFERMAXINDEX	(LOG_RINGBUFFERSIZE - 1)
#define LOG_RING				LOG_RINGBUFFERMAXINDEX

class cLogger {
private:
	char *ring_buffer;
	long rb_cur_position, rb_dumped_pos;
	
	bool waitForDump;			// BAD NAME OF VARIABLE
	long rb_occupied_space;		// for we can know if buffer is full
	
	bool Dump(long in);			// func for dump. run in another thread

	// synchro
	HANDLE hMutex;
	HANDLE hDumpEvent;
	HANDLE hDumpedEvent;
	long _rb_cur_position;
	int _message;				// '-1' mean exit
								// '1'	mean "Write I'm waitng"
								// '2'  mean  "Buffer is full enough for dumping"
	long semaphore;
	HANDLE hSemaphoreEvent;
	long DumpHalf;
	long empty;
	
	// thread
	HANDLE hDumpThread;
	friend DWORD WINAPI outerDumpFunc(LPVOID lpParam);

	// secondary
	inline long diff(long a);			// return diff between current position and flusher position

	// file
	FILE *f;

	//singletone
	cLogger();
	cLogger(const cLogger&){};
	cLogger& operator=(const cLogger&){};
public:
	static cLogger& Instance() {
		static cLogger logger;
		return logger;
	}

	~cLogger();


	void PutDebug(char *message);		// message must be null-terminated

	void SetWaitingOption(bool w);

	// debug
	long counter;
	long counter2;
};